﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Reflection;

namespace Logistics.Utils
{
    class DataConvert
    {
        #region DataTable转换为对象
        public static IList<T> ConvertToEntity<T>(DataSet ds)
        {
            IList<T> list = new List<T>();
            if (ds != null &&  ds.Tables.Count > 0 && ds.Tables[0].Rows.Count > 0)
            {
                foreach (DataRow row in ds.Tables[0].Rows)
                {
                    T entity = ConvertToEntity<T>(row);
                    list.Add(entity);
                }
            }
            return list;
        }

        public static T ConvertToEntity<T>(DataRow row)
        {
            Type type = typeof(T);
            T entity = Activator.CreateInstance<T>();
            if(row.Table.Columns!=null && row.Table.Columns.Count>0)
            {
                foreach(DataColumn col in row.Table.Columns)
                {
                    String colName = col.ColumnName;
                    PropertyInfo property = GetProperty(type, colName);
                    if (property != null)
                    {
                        SetPropertyValue(entity,property, row[colName]);
                    }
                }
            }
            return entity;
        }

        private static PropertyInfo GetProperty(Type type,String name)
        {
            if (String.IsNullOrEmpty(name)) return null;
            name = name.Trim();
            PropertyInfo property = type.GetProperty(name);
            if (property == null)
            {
                //遍历，忽略大小写
                PropertyInfo[] properties = type.GetProperties();
                foreach (var prop in properties)
                {
                    if (String.Compare(prop.Name, name, true) == 0)
                        property = prop;
                }
            }
            return property;
        }
        
        private static void SetPropertyValue(Object entity,PropertyInfo property,Object value)
        {
            if (value == null) return;
            Type type = property.PropertyType;
            Object typedValue = TypeConvert(type, value);
            property.SetValue(entity, typedValue, null);
        }

        private static Object TypeConvert(Type type, Object value)
        {
            if (value == null) return null;
            Object typedValue = null;
            if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>))
            {
                if (value == System.DBNull.Value)
                    return null;
                return TypeConvert(type.GetGenericArguments()[0], value);
            }
            else if (type == typeof(bool) && value.GetType()== typeof(string))
            {
                return (value.ToString() == "1" || (String.Compare(value.ToString(), "true", true)==0));
            }
            else
            {
                typedValue = Convert.ChangeType(value, type);
            }
            return typedValue;
        }
        #endregion

        #region 实体对象转换为SQL
        public static String GenerateInsertSQL(Object Entity,String TableName,String[] fieldNames,out IList<Object> Parameters)
        {
            Parameters = new List<Object>();
            if (Entity == null || String.IsNullOrEmpty(TableName)
                || fieldNames == null || fieldNames.Length==0) return "";
            String sql_fields = "";
            String sql_values = "";
            foreach (String fieldName in fieldNames)
            {
                Object value = GetValueFromEntity(Entity, fieldName);
                if (value != null)
                {
                    sql_fields += fieldName + ",";
                    sql_values += "?,";
                    Parameters.Add(value);
                }
            }
            if (sql_fields.EndsWith(","))
            {
                sql_fields = sql_fields.TrimEnd(',');
                sql_values = sql_values.TrimEnd(',');
            }
            if (!String.IsNullOrEmpty(sql_fields))
            {
                return "INSERT INTO "+TableName+" (" + sql_fields + ")VALUES(" + sql_values + ")";
            }
            return "";
        }
        public static String GenerateUpdateSQL(Object Entity, String TableName, String[] fieldNames,String PKeyName,Object PKeyValue, out IList<Object> Parameters)
        {
            Parameters = new List<Object>();
            if (Entity == null || String.IsNullOrEmpty(TableName)
                || fieldNames == null || fieldNames.Length == 0) return "";
            String sql_fields = "";
            foreach (String fieldName in fieldNames)
            {
                Object value = GetValueFromEntity(Entity, fieldName);
                sql_fields += fieldName + "=?,";
                Parameters.Add(value);
            }
            if (sql_fields.EndsWith(","))
            {
                sql_fields = sql_fields.TrimEnd(',');
            }
            String where = " Where " + PKeyName+"=?";
            Parameters.Add(PKeyValue);
            if (!String.IsNullOrEmpty(sql_fields))
            {
                return "UPDATE " + TableName + " SET " + sql_fields + where;
            }
            return "";
        }

        private static Object GetValueFromEntity(Object Entity,String propertyName)
        {
            Object value = null;
            PropertyInfo property = GetProperty(Entity.GetType(), propertyName);
            if(property!=null)
            {
                value = property.GetValue(Entity, null);
            }
            return value;
        }
        #endregion

        public static String GenerateInsertSQLFromDataRow(DataRow dataSource, String TableName, String[] fieldNames, out IList<Object> Parameters)
        {
            String FieldNames = "";
            String values = "";
            Parameters = new List<object>();
            foreach (String colName in fieldNames)
            {
                FieldNames += colName + ",";
                values += "?,";
                Object oval = dataSource[colName];
                Parameters.Add(oval);
            }
            if (FieldNames.EndsWith(","))
                FieldNames = FieldNames.Substring(0, FieldNames.Length - 1);
            if (values.EndsWith(","))
                values = values.Substring(0, values.Length - 1);
            String sql = "INSERT INTO " + TableName + " (" + FieldNames + ") VALUES (" + values + ")";
            return sql;
        }
    }
}
